package com.jwgf.common;

import android.content.Context;
import android.content.ContextWrapper;
import android.view.View;

import androidx.fragment.app.FragmentActivity;

import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.channels.FileChannel;
import java.util.Arrays;

public class Utility {

    // Using big-endian
    public static class ByteArrayUtils {
        public static byte[] long2ByteArray(long value) {
            ByteBuffer buffer = ByteBuffer.allocate(8);
            buffer.putLong(value);
            return buffer.array();
        }

        public static byte[] long2SwapByteArray(long value) {
            ByteBuffer buffer = ByteBuffer.allocate(8);
            buffer.order(ByteOrder.LITTLE_ENDIAN);
            buffer.putLong(value);
            return buffer.array();
        }

        public static long byteArray2Long(byte[] b) {
            ByteBuffer buffer = ByteBuffer.allocate(8);
            buffer.put(b);
            buffer.flip();// need flip
            return buffer.getLong();
        }

        public static byte[] int2ByteArray(int value) {
            ByteBuffer buffer = ByteBuffer.allocate(4);
            buffer.putInt(value);
            return buffer.array();
        }

        public static int byteArray2Int(byte[] b) {
            ByteBuffer buffer = ByteBuffer.allocate(4);
            buffer.put(b);
            buffer.flip();// need flip
            return buffer.getInt();
        }

        public static byte[] int2SwapByteArray(int value) {
            ByteBuffer buffer = ByteBuffer.allocate(4);
            value = (value << 16) | ((value & 0xffff0000) >> 16);
            buffer.putInt(value);
            return buffer.array();
        }

        public static int swapByteArray2Int(byte[] b) {
            ByteBuffer buffer = ByteBuffer.allocate(4);
            buffer.put(b[2]).put(b[3]).put(b[0]).put(b[1]);
            buffer.flip();// need flip
            return buffer.getInt();
        }

        public static byte[] short2ByteArray(short value) {
            ByteBuffer buffer = ByteBuffer.allocate(2);
            buffer.putShort(value);
            return buffer.array();
        }

        public static int asciiByte2ToInt(byte[] data) {
            String strData = new String(data);
            return Integer.parseInt(strData, 16);
        }


        public static short byteArray2Short(byte[] b) {
            ByteBuffer buffer = ByteBuffer.allocate(2);
            buffer.put(b);
            buffer.flip();// need flip
            return buffer.getShort();
        }

        public static byte[] short2SwapByteArray(short value) {
            ByteBuffer buffer = ByteBuffer.allocate(2);
            short swapValue = (short) (value << 8 | value >> 8);
            buffer.putShort(swapValue);
            return buffer.array();
        }

        public static short swapByteArray2Short(byte[] b) {
            ByteBuffer buffer = ByteBuffer.allocate(2);
            buffer.put(b[1]);
            buffer.put(b[0]);
            buffer.flip();// need flip
            return buffer.getShort();
        }

        public static byte[] float2ByteArray(float value) {
            return int2ByteArray(Float.floatToIntBits(value));
        }

        public static float byteArray2Float(byte[] b) {
            return Float.intBitsToFloat(byteArray2Int(b));
        }

        public static byte[] float2SwapByteArray(Float value) {
            return int2SwapByteArray(Float.floatToIntBits(value));
        }

        public static float swapByteArray2Float(byte[] b) {
            return Float.intBitsToFloat(swapByteArray2Int(b));
        }

        public static byte[] double2ByteArray(double value) {
            return long2ByteArray(Double.doubleToLongBits(value));
        }

        public static double byteArray2Double(byte[] b) {
            return Double.longBitsToDouble(byteArray2Long(b));
        }

        public static byte[] concatAll(byte[] first, byte[]... rest) {
            int totalLength = first.length;
            for (byte[] array : rest) {
                totalLength += array.length;
            }
            byte[] result = Arrays.copyOf(first, totalLength);
            int offset = first.length;
            for (byte[] array : rest) {
                System.arraycopy(array, 0, result, offset, array.length);
                offset += array.length;
            }
            return result;
        }
    }

    public static class BitUtils {
        public static int setBitValue(int source, int pos, int value) {
            int mask = 1 << pos;
            if (value > 0) {
                source |= mask;
            } else {
                source &= (~mask);
            }
            return source;
        }

        public static boolean getBitValue(int source, int pos) {
            int mask = 1 << pos;
            if ((source & mask) != 0) {
                return true;
            } else {
                return false;
            }
        }

        public static long setBitValue(long source, long pos, int value) {
            long mask = 1L << pos;
            if (value > 0) {
                source |= mask;
            } else {
                source &= (~mask);
            }
            return source;
        }

        public static boolean getBitValue(long source, long pos) {
            long mask = 1L << pos;
            if ((source & mask) != 0) {
                return true;
            } else {
                return false;
            }
        }
    }

    public static boolean isInteger(String value) {
        try {
            Integer.parseInt(value);
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }

    public static boolean isDouble(String value) {
        try {
            Double.parseDouble(value);
            if (value.contains("."))
                return true;
            return false;
        } catch (NumberFormatException e) {
            return false;
        }
    }

    public static boolean isNumber(String value) {
        return isInteger(value) || isDouble(value);
    }

    public static class FileUtils {

        public static void nioTransferCopy(String source, String target) {
            FileChannel in = null;
            FileChannel out = null;
            FileInputStream inStream = null;
            FileOutputStream outStream = null;
            try {
                inStream = new FileInputStream(source);
                outStream = new FileOutputStream(target);
                in = inStream.getChannel();
                out = outStream.getChannel();
                in.transferTo(0, in.size(), out);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    inStream.close();
                    in.close();
                    outStream.close();
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        public static void nioTransferCopy(File source, File target) {
            FileChannel in = null;
            FileChannel out = null;
            FileInputStream inStream = null;
            FileOutputStream outStream = null;
            try {
                inStream = new FileInputStream(source);
                outStream = new FileOutputStream(target);
                in = inStream.getChannel();
                out = outStream.getChannel();
                in.transferTo(0, in.size(), out);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    inStream.close();
                    in.close();
                    outStream.close();
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        public static void copyDirectory(String srcDirName, String destDirName) {
            File srcDir = new File(srcDirName);

            if (!destDirName.endsWith(File.separator)) {
                destDirName = destDirName + File.separator;
            }
            File destDir = new File(destDirName);
            if (!destDir.exists()) {
                destDir.mkdirs();
            }
            FileFilter ff = new FileFilter() {

                @Override
                public boolean accept(File pathname) {
                    String name = pathname.getName();
                    if (name.equals("lib") || name.equals("cache"))
                        return false;
                    return true;
                }
            };
            File[] files = srcDir.listFiles(ff);
            for (int i = 0; i < files.length; i++) {
                if (files[i].isFile()) {
                    nioTransferCopy(files[i].getAbsolutePath(), destDirName + files[i].getName());
                } else if (files[i].isDirectory()) {
                    copyDirectory(files[i].getAbsolutePath(), destDirName + files[i].getName());
                }
            }

        }
    }

    public static class ResourcesUtils {

        private static final String RES_ID = "id";
        private static final String RES_STRING = "string";
        private static final String RES_DRAWABLE = "drawable";
        private static final String RES_LAYOUT = "layout";
        private static final String RES_STYLE = "style";
        private static final String RES_COLOR = "color";
        private static final String RES_DIMEN = "dimen";
        private static final String RES_ANIM = "anim";
        private static final String RES_MENU = "menu";


        /**
         * 获取资源文件的id
         *
         * @param context
         * @param resName
         * @return
         */
        public static int getId(Context context, String resName) {
            return getResId(context, resName, RES_ID);
        }

        /**
         * 获取资源文件string的id
         *
         * @param context
         * @param resName
         * @return
         */
        public static int getStringId(Context context, String resName) {
            return getResId(context, resName, RES_STRING);
        }

        /**
         * 获取资源文件drable的id
         *
         * @param context
         * @param resName
         * @return
         */
        public static int getDrawbleId(Context context, String resName) {
            return getResId(context, resName, RES_DRAWABLE);
        }

        /**
         * 获取资源文件layout的id
         *
         * @param context
         * @param resName
         * @return
         */
        public static int getLayoutId(Context context, String resName) {
            return getResId(context, resName, RES_LAYOUT);
        }

        /**
         * 获取资源文件style的id
         *
         * @param context
         * @param resName
         * @return
         */
        public static int getStyleId(Context context, String resName) {
            return getResId(context, resName, RES_STYLE);
        }

        /**
         * 获取资源文件color的id
         *
         * @param context
         * @param resName
         * @return
         */
        public static int getColorId(Context context, String resName) {
            return getResId(context, resName, RES_COLOR);
        }

        /**
         * 获取资源文件dimen的id
         *
         * @param context
         * @param resName
         * @return
         */
        public static int getDimenId(Context context, String resName) {
            return getResId(context, resName, RES_DIMEN);
        }

        /**
         * 获取资源文件ainm的id
         *
         * @param context
         * @param resName
         * @return
         */
        public static int getAnimId(Context context, String resName) {
            return getResId(context, resName, RES_ANIM);
        }

        /**
         * 获取资源文件menu的id
         */
        public static int getMenuId(Context context, String resName) {
            return getResId(context, resName, RES_MENU);
        }

        /**
         * 获取资源文件ID
         *
         * @param context
         * @param resName
         * @param defType
         * @return
         */
        public static int getResId(Context context, String resName, String defType) {
            return context.getResources().getIdentifier(resName, defType, context.getPackageName());
        }

    }

    public static class ActivityUtils{
        public static FragmentActivity getActivityFromView(View view) {
            if (null != view) {
                Context context = view.getContext();
                while (context instanceof ContextWrapper) {
                    if (context instanceof FragmentActivity) {
                        return (FragmentActivity) context;
                    }
                    context = ((ContextWrapper) context).getBaseContext();
                }
            }
            return null;
        }
    }


}
